package com.stox.ui.javafx.charting.widget;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;

import org.controlsfx.control.PopOver;

import com.stox.ui.auto.javafx.JavaFXAutoUI;
import com.stox.ui.javafx.charting.model.plot.AbstractPlot;
import com.stox.ui.javafx.charting.model.plot.AbstractPrimaryPlot;
import com.stox.ui.javafx.charting.model.plot.VolumePlot;
import com.stox.ui.javafx.charting.view.ChartingView;

@SuppressWarnings("rawtypes")
public class PlotInfoPane extends Pane {

	private final Chart chart;
	private final VBox vBox = new VBox();
	
	public PlotInfoPane(Chart chart) {
		getStyleClass().add("plot-info-pane");
		vBox.getStyleClass().add("plot-info-vbox");
		this.chart = chart;
		getChildren().add(vBox);
	}
	
	public void update(){
		vBox.getChildren().clear();
		if(!(chart instanceof PrimaryChart)){
			AbstractPlot plot = chart.getFrontPlot();
			vBox.getChildren().add(new PlotInfoRow(plot));
		}
		for(Object object : chart.getPlots()){
			AbstractPlot plot = (AbstractPlot)object;
			if(plot instanceof VolumePlot){
				continue;
			}
			vBox.getChildren().add(new PlotInfoRow(plot));
		}
	}
	
	
	public Chart getChart() {
		return chart;
	}
	
}

@SuppressWarnings("rawtypes")
class PlotInfoRow extends HBox implements ChangeListener<Color>{
	
	private final Button closeButton = new Button();
	private final Button settingsButton = new Button();
	private final Label infoLabel = new Label();
	private final AbstractPlot plot;
	
	@Override
	public void changed(ObservableValue<? extends Color> observable,
			Color oldValue, Color newValue) {
		if(null != newValue){
			infoLabel.setTextFill(newValue);
		}
	}
	
	public PlotInfoRow(AbstractPlot plot) {
		getStyleClass().add("plot-info-row");
		this.plot = plot;
		plot.colorProperty().addListener(this);
		closeButton.getStyleClass().add("close");
		closeButton.setOnAction(new EventHandler<ActionEvent>(){
			@SuppressWarnings("unchecked")
			@Override
			public void handle(ActionEvent event) {
				ChartingView chartingView = plot.getChart().getChartingView();
				if(plot.getChart() instanceof SecondaryChart){
					AbstractPlot frontPlot = plot.getChart().getFrontPlot();
					if(plot.equals(frontPlot)){
						plot.getChart().getChartingView().removeSecondaryChart(plot.getChart());
						chartingView.layout();
					}
				}else{
					plot.getChart().removePlot(plot);
					chartingView.update();
				}
			}
		});
		settingsButton.getStyleClass().add("gear");
		settingsButton.setOnAction(new EventHandler<ActionEvent>(){
			@Override
			public void handle(ActionEvent event) {
				if(null == plot.getConfigurationBeanDescriptor()){
					return;
				}
				if(null == plot.getConfigurationUI()){
					Node node = new JavaFXAutoUI(plot.getConfigurationBeanDescriptor());
					BorderPane borderPane = new BorderPane();
					borderPane.setCenter(node);
					Region spacer = new Region();
					HBox.setHgrow(spacer, Priority.ALWAYS);
					Button okButton = new Button();
					okButton.getStyleClass().add("checked");
					okButton.getStyleClass().add("stox-button");
					okButton.setOnAction(new EventHandler<ActionEvent>(){
						@Override
						public void handle(ActionEvent event) {
							plot.getConfigurationUI().hide();
							plot.getData().clear();
							plot.getChart().getChartingView().update();
							plot.getChart().getPlotInfoPane().update();
						}
					});
					Button cancelButton = new Button();
					cancelButton.getStyleClass().add("cross");
					cancelButton.getStyleClass().add("stox-button");
					cancelButton.setOnAction(new EventHandler<ActionEvent>(){
						@Override
						public void handle(ActionEvent event) {
							plot.getConfigurationUI().hide();
						}
					});
					
					borderPane.setBottom(new HBox(spacer, okButton, cancelButton));
					plot.setConfigurationUI(new ConfigurationPopOver(borderPane));
				}
				plot.getConfigurationUI().show(settingsButton);
			}
		});
		
		infoLabel.setText(plot.getModel().toString());
		
		if(null != plot.getColor()){
			infoLabel.setTextFill(plot.getColor());
		}
		
		if(plot instanceof AbstractPrimaryPlot){
			getChildren().addAll(closeButton, infoLabel);
		}else{
			getChildren().addAll(closeButton, settingsButton, infoLabel);
		}
	}
	
}

class ConfigurationPopOver extends PopOver{
	
	public ConfigurationPopOver(Node node) {
		setId("configuration-pop-over");
		setAutoFix(true);
		setAutoHide(true);
		setHideOnEscape(true);
		setContentNode(node);
	}
	
}